package avicit.bdp.lineage.druid.process.sqlselectquery;

import avicit.bdp.lineage.druid.anotation.SQLObjectType;
import avicit.bdp.lineage.druid.contants.ParserConstant;
import avicit.bdp.lineage.druid.model.ColumnNode;
import avicit.bdp.lineage.druid.model.TableNode;
import avicit.bdp.lineage.druid.model.TreeNode;
import avicit.bdp.lineage.druid.process.ProcessorRegister;
import avicit.bdp.lineage.druid.process.SqlExprContent;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.statement.SQLSelectItem;
import com.alibaba.druid.sql.ast.statement.SQLSelectQuery;
import com.alibaba.druid.sql.ast.statement.SQLSelectQueryBlock;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * <p>
 * PGSelectQueryBlock
 * use case:
 * create view view_test as
 * select temp.a1,temp.a2 (
 * select a1,a2 from table1
 * ) temp
 * </p>
 *
 */
@SQLObjectType(clazz = SQLSelectQueryBlock.class)
public class SQLSelectQueryBlockProcessor extends AbstractSQLSelectQueryProcessor {

    @Override
    public void process(String dbType, AtomicInteger sequence, TreeNode<TableNode> parent,
                        SQLSelectQuery sqlSelectQuery) {
        SQLSelectQueryBlock sqlSelectQueryBlock = (SQLSelectQueryBlock) sqlSelectQuery;
        // 建立表节点，并关系父级关系
        TableNode proxyTable = TableNode.builder()
                .isVirtualTemp(true)
                .expression(SQLUtils.toSQLString(sqlSelectQueryBlock))
                .name(ParserConstant.TEMP_TABLE_PREFIX + sequence.incrementAndGet())
                .alias(this.getSubqueryTableSourceAlias(sqlSelectQueryBlock))
                .build();
        TreeNode<TableNode> proxyNode = TreeNode.of(proxyTable);
        parent.addChild(proxyNode);
        // 生成字段
        List<ColumnNode> columnList = sqlSelectQueryBlock.getSelectList()
                .stream()
                .map(sqlSelectItem -> this.convertSelectItem2Column(dbType, sqlSelectItem))
                .collect(Collectors.toList());
        // TODO 如果字段的表名没有, 考虑填充表名，以提高字段来源检索。
        // 表字段填充到表
        proxyTable.getColumns().addAll(columnList);
        // 继续向下处理
        ProcessorRegister
                .getTableSourceProcessor(sqlSelectQueryBlock.getFrom().getClass())
                .process(dbType, sequence, proxyNode, sqlSelectQueryBlock.getFrom());
    }



}
